package whf.framework.web.tag;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;

import whf.framework.util.ParamUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;
import whf.framework.web.Constants;

/**
 * 只用来输出jsp中的扩展属性，替换java代码
 * @author wanghaifeng
 *
 */
@SuppressWarnings(value={"serial", "unchecked"})
public class ExtAttributeTag extends HtmlTag {
	/**
	 * 是否将空值输出；
	 */
	private boolean enableEmpty;
	
	/**
	 * 属性值来源
	 */
	private String source;
	
	/**
	 * 固有参数
	 */
	private List<String> fixedParams;
	
	/**
	 * 忽略参数
	 */
	private List<String> ignoreParams;
	
	public void setEnableEmpty(boolean b){
		this.enableEmpty = b;
	}
	
	public void setSource(String source){
		this.source = source;
	}
	
	public void setFixedParams(Object obj){
		if(obj == null) return;
		if(obj.getClass().isArray()){
			if(this.fixedParams == null) 
				this.fixedParams = Utils.newArrayList();
			int length = Array.getLength(obj);
			for(int i=0; i< length; i++){
				Object o = Array.get(obj, i);
				if(o == null) continue;
				this.fixedParams.add(o.toString());
			}
		} else {
			if(this.fixedParams == null) 
				this.fixedParams = Utils.newArrayList();
			String[] arr = StringUtils.split(obj.toString(), ",");
			for(int i=0; i<arr.length; i++){
				this.fixedParams.add(arr[i]);
			}
		}
	}
	
	public void setIgnoreParams(Object obj) {
		if(obj == null) return;
		if(obj.getClass().isArray()){
			if(this.ignoreParams == null) 
				this.ignoreParams = Utils.newArrayList();
			int length = Array.getLength(obj);
			for(int i=0; i< length; i++){
				Object o = Array.get(obj, i);
				if(o == null) continue;
				this.ignoreParams.add(o.toString());
			}
		} else {
			if(this.ignoreParams == null) 
				this.ignoreParams = Utils.newArrayList();
			String[] arr = StringUtils.split(obj.toString(), ",");
			for(int i=0; i<arr.length; i++){
				this.ignoreParams.add(arr[i]);
			}
		}
	}

	@Override
	public int doStartTag() throws JspException {
		Map<String, String> requestReservedParameters = ParamUtils.getKeepParameters(request());
		if(!StringUtils.isEmpty(this.source)) {
			if(this.source.indexOf("application") >= 0) {
				Map<String, String> map = (Map<String, String>)request().getSession().getServletContext().getAttribute(Constants.REQUEST_KEEP_PARAMETERS);
				if(map != null)
					requestReservedParameters.putAll(map);
			}
			if(this.source.indexOf("session") >= 0) {
				Map<String, String> map = (Map<String, String>)request().getSession().getAttribute(Constants.REQUEST_KEEP_PARAMETERS);
				if(map != null)
					requestReservedParameters.putAll(map);
			}
			if(this.source.indexOf("request") >= 0) {
				Map<String, String> map = (Map<String, String>)request().getAttribute(Constants.REQUEST_KEEP_PARAMETERS);
				if(map != null)
					requestReservedParameters.putAll(map);
			}
		}
		Enumeration<String> attributeNames = request().getAttributeNames();
		while(attributeNames.hasMoreElements()) {
			String attributeName = attributeNames.nextElement();
			if(attributeName.startsWith(Constants.REQUEST_KEEP_PARAMETER_PREFFIX)) {
				Object value = request().getAttribute(attributeName);
				if(value instanceof Map || value instanceof Collection) continue;
				requestReservedParameters.put(attributeName, value == null?"": value.toString());
			}
		}
		if(this.fixedParams != null) {
			for(String fp: this.fixedParams) {
				if(!requestReservedParameters.containsKey(fp)) {
					requestReservedParameters.put(fp, null);
				}
			}
		}
		if(this.ignoreParams != null) {
			for(String fp: this.ignoreParams) {
				requestReservedParameters.remove(fp);
			}
		}
		for(String pn: requestReservedParameters.keySet()) {
			String pv = requestReservedParameters.get(pn);
			if(StringUtils.isEmpty(pv) && !this.enableEmpty) continue;
			if(this.ignoreParams != null && this.ignoreParams.contains(pn)) continue;
			if(this.ignoreParams != null && this.ignoreParams.contains("_$_trc") && pn.startsWith("_$_") && pn.endsWith("trc")) continue;
			if(pv == null) pv = "";
			super.printInput("hidden", pn, pv);
		}
		this.enableEmpty = false;
		this.source = "";
		this.fixedParams = null;
		this.ignoreParams = null;
		super.release();
		return SKIP_BODY;
	}

}
